import { useState, useCallback, useMemo, useRef } from 'react';
import { useCachedData } from './useMeituanData';

/**
 * 性能优化Hook
 * 提供虚拟滚动、懒加载、缓存等性能优化功能
 */
export const usePerformance = () => {
  const cacheRef = useRef(new Map());
  const observerRef = useRef(null);
  
  /**
   * 虚拟滚动Hook
   * @param {Array} items - 数据列表
   * @param {number} itemHeight - 每行高度
   * @param {number} containerHeight - 容器高度
   */
  const useVirtualScroll = (items = [], itemHeight = 60, containerHeight = 400) => {
    const [scrollTop, setScrollTop] = useState(0);
    
    const visibleItems = useMemo(() => {
      const startIndex = Math.floor(scrollTop / itemHeight);
      const endIndex = Math.min(
        startIndex + Math.ceil(containerHeight / itemHeight) + 1,
        items.length
      );
      
      return items.slice(startIndex, endIndex);
    }, [items, scrollTop, itemHeight, containerHeight]);

    const totalHeight = items.length * itemHeight;
    const offsetY = Math.floor(scrollTop / itemHeight) * itemHeight;

    const handleScroll = useCallback((e) => {
      setScrollTop(e.target.scrollTop);
    }, []);

    return {
      visibleItems,
      totalHeight,
      offsetY,
      handleScroll,
    };
  };

  /**
   * 图片懒加载Hook
   */
  const useLazyLoad = () => {
    const [loadedImages, setLoadedImages] = useState(new Set());

    const observe = useCallback((element, src) => {
      if (!observerRef.current) {
        observerRef.current = new IntersectionObserver(
          (entries) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                const img = entry.target;
                img.src = src;
                setLoadedImages(prev => new Set(prev).add(src));
                observerRef.current.unobserve(img);
              }
            });
          },
          { rootMargin: '50px' }
        );
      }

      if (element) {
        observerRef.current.observe(element);
      }
    }, []);

    const unobserve = useCallback((element) => {
      if (observerRef.current && element) {
        observerRef.current.unobserve(element);
      }
    }, []);

    return { observe, unobserve, loadedImages };
  };

  /**
   * 防抖Hook
   */
  const useDebounce = (callback, delay) => {
    const timeoutRef = useRef(null);

    const debouncedCallback = useCallback((...args) => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      
      timeoutRef.current = setTimeout(() => {
        callback(...args);
      }, delay);
    }, [callback, delay]);

    const cancel = useCallback(() => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    }, []);

    return { debouncedCallback, cancel };
  };

  /**
   * 节流Hook
   */
  const useThrottle = (callback, delay) => {
    const lastCallRef = useRef(0);
    const timeoutRef = useRef(null);

    const throttledCallback = useCallback((...args) => {
      const now = Date.now();
      
      if (now - lastCallRef.current >= delay) {
        lastCallRef.current = now;
        callback(...args);
      } else {
        if (timeoutRef.current) {
          clearTimeout(timeoutRef.current);
        }
        
        timeoutRef.current = setTimeout(() => {
          lastCallRef.current = Date.now();
          callback(...args);
        }, delay - (now - lastCallRef.current));
      }
    }, [callback, delay]);

    const cancel = useCallback(() => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    }, []);

    return { throttledCallback, cancel };
  };

  /**
   * 分页Hook
   */
  const usePagination = (totalItems = 0, initialPageSize = 10) => {
    const [current, setCurrent] = useState(1);
    const [pageSize, setPageSize] = useState(initialPageSize);

    const totalPages = Math.ceil(totalItems / pageSize);

    const handlePageChange = useCallback((page, newPageSize) => {
      setCurrent(page);
      if (newPageSize) {
        setPageSize(newPageSize);
      }
    }, []);

    const reset = useCallback(() => {
      setCurrent(1);
      setPageSize(initialPageSize);
    }, [initialPageSize]);

    return {
      current,
      pageSize,
      totalPages,
      totalItems,
      handlePageChange,
      reset,
    };
  };

  /**
   * 缓存Hook
   */
  const useCache = (key, maxAge = 5 * 60 * 1000) => {
    const [cache, setCache] = useState(() => {
      const cached = cacheRef.current.get(key);
      if (cached && Date.now() - cached.timestamp < maxAge) {
        return cached.data;
      }
      return null;
    });

    const set = useCallback((data) => {
      cacheRef.current.set(key, {
        data,
        timestamp: Date.now(),
      });
      setCache(data);
    }, [key]);

    const get = useCallback(() => {
      const cached = cacheRef.current.get(key);
      if (cached && Date.now() - cached.timestamp < maxAge) {
        return cached.data;
      }
      return null;
    }, [key, maxAge]);

    const clear = useCallback(() => {
      cacheRef.current.delete(key);
      setCache(null);
    }, [key]);

    const clearAll = useCallback(() => {
      cacheRef.current.clear();
      setCache(null);
    }, []);

    return { cache, set, get, clear, clearAll };
  };

  /**
   * 无限滚动Hook
   */
  const useInfiniteScroll = (loadMore, hasMore) => {
    const [loading, setLoading] = useState(false);
    const observerRef = useRef(null);

    const lastElementRef = useCallback(
      (node) => {
        if (loading) return;
        if (observerRef.current) observerRef.current.disconnect();

        observerRef.current = new IntersectionObserver((entries) => {
          if (entries[0].isIntersecting && hasMore) {
            setLoading(true);
            loadMore().finally(() => setLoading(false));
          }
        });

        if (node) observerRef.current.observe(node);
      },
      [loading, hasMore, loadMore]
    );

    return { loading, lastElementRef };
  };

  /**
   * 计算Hook - 避免重复计算
   */
  const useMemoized = (compute, deps) => {
    const lastDepsRef = useRef(deps);
    const lastResultRef = useRef();

    const depsChanged = deps.length !== lastDepsRef.current.length ||
      deps.some((dep, i) => dep !== lastDepsRef.current[i]);

    if (depsChanged) {
      lastResultRef.current = compute();
      lastDepsRef.current = deps;
    }

    return lastResultRef.current;
  };

  /**
   * 批量请求Hook
   */
  const useBatchRequest = (requests, batchSize = 5) => {
    const [loading, setLoading] = useState(false);
    const [results, setResults] = useState([]);
    const [errors, setErrors] = useState([]);

    const execute = useCallback(async () => {
      setLoading(true);
      setResults([]);
      setErrors([]);

      const batches = [];
      for (let i = 0; i < requests.length; i += batchSize) {
        batches.push(requests.slice(i, i + batchSize));
      }

      const allResults = [];
      const allErrors = [];

      for (const batch of batches) {
        try {
          const batchResults = await Promise.allSettled(batch);
          batchResults.forEach((result) => {
            if (result.status === 'fulfilled') {
              allResults.push(result.value);
            } else {
              allErrors.push(result.reason);
            }
          });
        } catch (error) {
          allErrors.push(error);
        }
      }

      setResults(allResults);
      setErrors(allErrors);
      setLoading(false);

      return { results: allResults, errors: allErrors };
    }, [requests, batchSize]);

    return { loading, results, errors, execute };
  };

  return {
    useVirtualScroll,
    useLazyLoad,
    useDebounce,
    useThrottle,
    usePagination,
    useCache,
    useInfiniteScroll,
    useMemoized,
    useBatchRequest,
  };
};